﻿namespace VideoTools.SubtitleEdit.Common
{
    public static class StringExtensions
    {
        public static char[] UnicodeControlChars { get; } = { '\u200E', '\u200F', '\u202A', '\u202B', '\u202C', '\u202D', '\u202E' };

        public static List<string> SplitToLines(this string s) => SplitToLines(s, s.Length);

        public static List<string> SplitToLines(this string s, int max)
        {
            //original non-optimized version: return source.Replace("\r\r\n", "\n").Replace("\r\n", "\n").Replace('\r', '\n').Replace('\u2028', '\n').Split('\n');

            var lines = new List<string>();
            var start = 0;
            var i = 0;

            if (s.Length < max)
            {
                max = s.Length;
            }

            while (i < max)
            {
                var ch = s[i];
                if (ch == '\r')
                {
                    if (i < max - 2 && s[i + 1] == '\r' && s[i + 2] == '\n') // \r\r\n
                    {
                        lines.Add(s.Substring(start, i - start));
                        i += 3;
                        start = i;
                        continue;
                    }

                    if (i < max - 1 && s[i + 1] == '\n') // \r\n
                    {
                        lines.Add(s.Substring(start, i - start));
                        i += 2;
                        start = i;
                        continue;
                    }

                    lines.Add(s.Substring(start, i - start));
                    i++;
                    start = i;
                    continue;
                }

                if (ch == '\n' || ch == '\u2028')
                {
                    lines.Add(s.Substring(start, i - start));
                    i++;
                    start = i;
                    continue;
                }

                i++;
            }

            lines.Add(s.Substring(start, i - start));
            return lines;
        }

        public static int CountWords(this string source)
        {
            return HtmlUtil.RemoveHtmlTags(source, true).Split(new[] { ' ', '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries).Length;
        }

        public static int IndexOfAny(this string s, string[] words, StringComparison comparisonType)
        {
            if (words == null || string.IsNullOrEmpty(s))
            {
                return -1;
            }

            for (var i = 0; i < words.Length; i++)
            {
                var idx = s.IndexOf(words[i], comparisonType);
                if (idx >= 0)
                {
                    return idx;
                }
            }

            return -1;
        }

        public static bool IsOnlyControlCharactersOrWhiteSpace(this string s)
        {
            if (s == null)
            {
                return true;
            }

            var max = s.Length;
            for (var index = 0; index < max; index++)
            {
                var ch = s[index];
                if (!char.IsControl(ch) && !char.IsWhiteSpace(ch) && !UnicodeControlChars.Contains(ch))
                {
                    return false;
                }
            }

            return true;
        }

        public static string RemoveChar(this string value, char charToRemove)
        {
            char[] array = new char[value.Length];
            int arrayIndex = 0;
            for (int i = 0; i < value.Length; i++)
            {
                char ch = value[i];
                if (ch != charToRemove)
                {
                    array[arrayIndex++] = ch;
                }
            }

            return new string(array, 0, arrayIndex);
        }

        public static decimal CountCharacters(this string value, bool forCps)
        {
            return 0;
        }
    }
}
